#include "ViewModel.h"
#include "View.h"
#include "Model.h"
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <conio.h>

void initViewModel()
{
    showHeader();
    showPageMain();
    handleMain();
}

PNode locatePage(int *pageIndex)
{
    PNode node = getHead();
    for (int index = 0; index < *pageIndex; ++index)
    {
        for (int i = 1; i <= N_LIST; ++i)
        {
            if (node != NULL && node->next != NULL)
            {
                node = node->next;
            }
            else
            {
                *pageIndex = index;
                return node;
            }
        }
    }
    return node;
}

void selectPage(bool flag, int *pageIndex, HANDLE hOut)
{
    if (flag)
    {
        if (*pageIndex > 0)
        {
            --(*pageIndex);
            PNode node = locatePage(pageIndex);
            clearScreenRect(5, 5 + N_LIST);
            printData(node, *pageIndex);
        }
    }
    else
    {
        int index = *pageIndex;
        ++(*pageIndex);
        PNode node = locatePage(pageIndex);
        if (*pageIndex > index)
        {
            clearScreenRect(5, 5 + N_LIST);
            printData(node, *pageIndex);
        }
    }
}

void printData(PNode node, int pageIndex)
{
    cursorPos(0, 5);
    int startIndex = pageIndex * N_LIST;
    for (int i = 1; node != NULL && i <= N_LIST; ++i, node = node->next)
    {
        printf(" %4u    |  %-12llu| ", i + startIndex, node->id);
        printf(node->name);
        cursorPos(39, 4 + i);
        printf("|%14.2lf\n", node->money);
    }
}

void cmdSearch()
{
    printf("请输入学号：");
    uint64_t id = 0;
    char idStr[N_STR];
    char *pEnd = NULL;
    gets(idStr);
    clearScreenRect(4, 28);
    //字符串转为十进制无符号整形
    id = strtoull(idStr, &pEnd, 10);
    if (*pEnd != '\0' || id == 0)
    {
        printf("无效的输入！\a\n");
        printf("按任意键继续...");
        _getch();
        return;
    }
    PNode node = get(getHead(), id);
    if (node == NULL)
    {
        printf("未查找到学号为 %llu 的数据！\a\n", id);
    }
    else
    {
        printf("查询结果如下：\n");
        printf("     学号     |     姓名     |       存款\n");
        printf("  %-12llu| %s", node->id, node->name);
        cursorPos(29, 6);
        printf("|%14.2lf\n", node->money);
    }
    printf("按任意键继续...");
    _getch();
}

void cmdSort(Criteria crit)
{
    sort(crit);
    writeData();
}

void cmdWrite()
{
    char idStr[N_STR];
    char nameStr[N_NAME];
    char moneyStr[N_STR];
    char *pEnd1 = NULL;
    char *pEnd2 = NULL;
    printf("按任意键开始(按ESC键退出)");
    if (_getch() == VK_ESCAPE)
    {
        return;
    }
    clearScreenRect(4, 28);
    printf("请输入待写入记录的学号：");
    gets(idStr);
    printf("请输入待写入记录的姓名：");
    gets(nameStr);
    printf("请输入待写入记录的金额：");
    gets(moneyStr);
    clearScreenRect(4, 28);
    uint64_t id = 0;
    double money = 0;

    id = strtoull(idStr, &pEnd1, 10);
    money = strtod(moneyStr, &pEnd2);
    if (*pEnd1 != '\0' || *pEnd2 != '\0' || id == 0 || money < 0 || strlen(nameStr) == 0)
    {
        printf("无效的输入！\a\n");
        printf("按任意键继续...");
        _getch();
        return;
    }
    PNode node = get(getHead(), id);
    if (node != NULL)
    {
        printf("待写入记录与已有记录冲突，是否继续写入(y/n)？\n");
        tag_confirm:
        switch (_getch())
        {
            case 'Y':
            case VK_RETURN:
                break;
            case 'N':
            case VK_ESCAPE:
                printf("已取消修改！\n");
                printf("按任意键继续...");
                _getch();
                return;
            default:
                printf("\a无效输入！请重新决定是否继续写入(y/n)？\n");
                goto tag_confirm;
        }
    }
    set(node, id, nameStr, money);
    writeData();
    printf("已完成修改！\n");
    printf("按任意键继续...");
    _getch();
}

void cmdDelete()
{
    if (getHead() == NULL)
    {
        printf("当前数据区为空！\a\n");
        printf("按任意键继续...");
        _getch();
        return;
    }
    char idStr[N_STR];
    uint64_t id = 0;
    char *pEnd = NULL;
    printf("按任意键开始(按ESC键退出)");
    if (_getch() == VK_ESCAPE)
    {
        return;
    }
    clearScreenRect(4, 28);
    printf("请输入要删除的记录的学号：");
    gets(idStr);
    clearScreenRect(4, 28);
    id = strtoull(idStr, &pEnd, 10);
    if (*pEnd != '\0' || id == 0)
    {
        printf("无效的输入！\a\n");
        printf("按任意键继续...");
        _getch();
        return;
    }
    if (delete(id))
    {
        writeData();
        printf("已删除该记录！\n");
    }
    else
    {
        printf("未查找到该记录！\a\n");
    }
    printf("按任意键继续...");
    _getch();
}

void cmdDeposit()
{
    if (getHead() == NULL)
    {
        printf("当前数据区为空！\a\n");
        printf("按任意键继续...");
        _getch();
        return;
    }
    char idStr[N_STR];
    char moneyStr[N_STR];
    uint64_t id = 0;
    double money = 0;
    char *pEnd1 = NULL;
    char *pEnd2 = NULL;
    printf("按任意键开始(按ESC键退出)");
    if (_getch() == VK_ESCAPE)
    {
        return;
    }
    clearScreenRect(4, 28);
    printf("请输入学号：");
    gets(idStr);
    printf("请输入存入金额：");
    gets(moneyStr);
    clearScreenRect(4, 28);
    id = strtoull(idStr, &pEnd1, 10);
    money = strtod(moneyStr, &pEnd2);
    if (*pEnd1 != '\0' || *pEnd2 != '\0' || id == 0 || money <= 0)
    {
        printf("无效的输入！\a\n");
        printf("按任意键继续...");
        _getch();
        return;
    }
    PNode node = get(getHead(), id);
    if (node == NULL)
    {
        printf("未查找到学号为 %llu 的相关记录！\a\n", id);
    }
    else
    {
        node->money += money;
        writeData();
        printf("已向学号为 %llu 的账户存入金额 %.2lf 元，当前账户余额 %.2lf 元\n", id, money, node->money);
    }
    printf("按任意键继续...");
    _getch();
}
void cmdWithdraw()
{
    if (getHead() == NULL)
    {
        printf("当前数据区为空！\a\n");
        printf("按任意键继续...");
        _getch();
        return;
    }
    char idStr[N_STR];
    char moneyStr[N_STR];
    uint64_t id = 0;
    double money = 0;
    char *pEnd1 = NULL;
    char *pEnd2 = NULL;
    printf("按任意键开始(按ESC键退出)");
    if (_getch() == VK_ESCAPE)
    {
        return;
    }
    clearScreenRect(4, 28);
    printf("请输入学号：");
    gets(idStr);
    printf("请输入取出金额：");
    gets(moneyStr);
    clearScreenRect(4, 28);
    id = strtoull(idStr, &pEnd1, 10);
    money = strtod(moneyStr, &pEnd2);
    if (*pEnd1 != '\0' || *pEnd2 != '\0' || id == 0 || money <= 0)
    {
        printf("无效的输入！\a\n");
        printf("按任意键继续...");
        _getch();
        return;
    }
    PNode node = get(getHead(), id);
    if (node == NULL)
    {
        printf("未查找到学号为 %llu 的相关记录！\a\n", id);
    }
    else if (node->money < money)
    {
        printf("余额不足！待取出金额 %.2lf 元，当前账户余额 %.2lf 元\a\n", money, node->money);
    }
    else
    {
        node->money -= money;
        writeData();
        printf("已从学号为 %llu 的账户取出金额 %.2lf 元，当前账户余额 %.2lf 元\n", id, money, node->money);
    }
    printf("按任意键继续...");
    _getch();
}
void cmdTransfer()
{
    if (getHead() == NULL)
    {
        printf("当前数据区为空！\a\n");
        printf("按任意键继续...");
        _getch();
        return;
    }
    char idFromStr[N_STR];
    char idToStr[N_STR];
    char moneyStr[N_STR];
    uint64_t idFrom = 0;
    uint64_t idTo = 0;
    double money = 0;
    char *pEnd1 = NULL;
    char *pEnd2 = NULL;
    char *pEnd3 = NULL;
    printf("按任意键开始(按ESC键退出)");
    if (_getch() == VK_ESCAPE)
    {
        return;
    }
    clearScreenRect(4, 28);
    printf("请输入出账学号：");
    gets(idFromStr);
    printf("请输入入账学号：");
    gets(idToStr);
    printf("请输入转账金额：");
    gets(moneyStr);
    clearScreenRect(4, 28);
    idFrom = strtoull(idFromStr, &pEnd1, 10);
    idTo = strtoull(idToStr, &pEnd2, 10);
    money = strtod(moneyStr, &pEnd3);
    if (*pEnd1 != '\0' || *pEnd2 != '\0' || *pEnd3 != '\0' || idFrom == 0 || idTo == 0 || money <= 0)
    {
        printf("无效的输入！\a\n");
        printf("按任意键继续...");
        _getch();
        return;
    }
    PNode nodeF = get(getHead(), idFrom);
    if (nodeF == NULL)
    {
        printf("\a未查找到学号为 %llu 的相关记录！\n", idFrom);
        goto tag_end;
    }
    if (nodeF->money < money)
    {
        printf("\a余额不足！待转出金额 %.2lf 元，当前账户余额 %.2lf 元\n", money, nodeF->money);
        goto tag_end;
    }
    PNode nodeT = get(getHead(), idTo);
    if (nodeT == NULL)
    {
        printf("\a未查找到学号为 %llu 的相关记录！\n", idTo);
        goto tag_end;
    }
    nodeF->money -= money;
    nodeT->money += money;
    writeData();
    printf("成功转账！\n");
    printf("账户：%llu->%llu；金额：%.2lf 元\n", idFrom, idTo, money);
    tag_end:
    printf("按任意键继续...");
    _getch();
}

void cmdExit()
{
    shutdownView();
    shutdownModel();
    exit(0);
}